﻿// GDBTreeCtrl.cpp: 实现文件
//

#include "stdafx.h"
#include "zChecker.h"
#include "GDBTreeCtrl.h"

#include "MainFrm.h"
#include "CheckerDoc.h"
#include "CheckerView.h"

#define CK_GDB_TREE_ROOT_NODE	0
#define CK_GDB_TREE_FOLD_NODE	1
#define CK_GDB_TREE_PONT_NODE	2
#define CK_GDB_TREE_LINE_NODE	3
#define CK_GDB_TREE_POLG_NODE	4
#define CK_GDB_TREE_GRID_NODE	5

// CGDBTreeCtrl

IMPLEMENT_DYNAMIC(CGDBTreeCtrl, CTreeCtrl)

CGDBTreeCtrl::CGDBTreeCtrl()
{

}

CGDBTreeCtrl::~CGDBTreeCtrl()
{
}


BEGIN_MESSAGE_MAP(CGDBTreeCtrl, CTreeCtrl)
	ON_WM_CREATE()
	ON_WM_SIZE()
	ON_NOTIFY_REFLECT(NM_CLICK, &CGDBTreeCtrl::OnNMClick)
	ON_NOTIFY_REFLECT(NM_RCLICK, &CGDBTreeCtrl::OnNMRClick)
	ON_NOTIFY_REFLECT(NM_DBLCLK, &CGDBTreeCtrl::OnNMDblclk)
	ON_COMMAND(ID_GDB_TREE_REFRESH, &CGDBTreeCtrl::OnGdbTreeRefresh)
END_MESSAGE_MAP()



// CGDBTreeCtrl 消息处理程序




int CGDBTreeCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CTreeCtrl::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  在此添加您专用的创建代码

	CBitmap bmp;
	if (bmp.LoadBitmap(IDB_BITMAP_GDB_TREE_16))
	{
		m_il.Create(16, 16, ILC_COLOR32 | ILC_MASK, 0, 0);
		m_il.Add(&bmp, RGB(255, 0, 255));
		int nCount = m_il.GetImageCount();
		for (int i = 1; i < nCount; i++)         //support 16
		{
			m_il.SetOverlayImage(i, i);
		}
		SetImageList(&m_il, TVSIL_NORMAL);
	}

	HTREEITEM  m_hRoot = InsertItem("GDB数据库", CK_GDB_TREE_ROOT_NODE, CK_GDB_TREE_ROOT_NODE);;

	return 0;
}


void CGDBTreeCtrl::OnSize(UINT nType, int cx, int cy)
{
	CTreeCtrl::OnSize(nType, cx, cy);

	// TODO: 在此处添加消息处理程序代码

}


void CGDBTreeCtrl::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult)
{
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;
}


void CGDBTreeCtrl::OnNMRClick(NMHDR *pNMHDR, LRESULT *pResult)
{
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;

	CPoint pt,spt;
	GetCursorPos(&pt);
	spt = pt;
	ScreenToClient(&pt);

	UINT uFlag = 0;
	HTREEITEM hItem = HitTest(pt, &uFlag);
	if ((NULL == hItem) || !(TVHT_ONITEM&uFlag))
	{
		return;
	}

	HTREEITEM hRoot = GetRootItem();
	if (hItem == hRoot)
	{
		CMenu m, *mn;
		m.LoadMenu(IDR_RMENU_GDB_TREE_ROOT);//加载菜单资源
		mn = m.GetSubMenu(0);//获取菜单子项
		mn->TrackPopupMenu(TPM_LEFTALIGN, spt.x, spt.y, this);    //显示菜单
	}
}


void CGDBTreeCtrl::OnNMDblclk(NMHDR *pNMHDR, LRESULT *pResult)
{
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;

	CPoint pt, spt;
	GetCursorPos(&pt);
	spt = pt;
	ScreenToClient(&pt);

	UINT uFlag = 0;
	HTREEITEM hItem = HitTest(pt, &uFlag);
	if ((NULL == hItem) || !(TVHT_ONITEM&uFlag))
	{
		return;
	}

	HTREEITEM hRoot = GetRootItem();
	if (GetParentItem(hItem) == hRoot)
	{
		CString strDatasetName = GetItemText(hItem);
		CheckerView* pView = (CheckerView*)((CMainFrame*)AfxGetMainWnd())->GetActiveView();

		HRESULT hr;
		ILayerPtr pLayer;
		
		//图层节点
		esriDatasetType type = (esriDatasetType)GetItemData(hItem);
		switch (type)
		{
		case esriDTFeatureClass:
		{
			IFeatureWorkspacePtr pFeatureWorkspace(m_pWorkspace);
			IFeatureClassPtr pFeaureClass;

			hr = pFeatureWorkspace->OpenFeatureClass(CComBSTR(strDatasetName), &pFeaureClass);
			if (FAILED(hr))
			{
				return;
			}

			IFeatureLayerPtr pFeatureLayer(CLSID_FeatureLayer);
			pFeatureLayer->putref_FeatureClass(pFeaureClass);
			pFeatureLayer->put_Name(CComBSTR(strDatasetName));

			pLayer = pFeatureLayer;
			pView->AddLayer(pLayer);
			pView->RefreshMap();

		}
			break;
		case esriDTRasterDataset:
		{
			IRasterWorkspaceExPtr  pRasterWorkspace(m_pWorkspace);
			IRasterDatasetPtr pRasterDataset = NULL;
			hr = pRasterWorkspace->OpenRasterDataset(CComBSTR(strDatasetName), &pRasterDataset);
			if (FAILED(hr))
			{
				AfxMessageBox("Error");
				return;
			}

			IRasterLayerPtr pRasterLayer(CLSID_RasterLayer);
			pRasterLayer->CreateFromDataset(pRasterDataset);

			pLayer = pRasterLayer;
			pView->AddLayer(pLayer);
			pView->RefreshMap();
		}
			break;
		}
	}
}


BOOL CGDBTreeCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此添加专用代码和/或调用基类
	cs.style |= TVS_HASLINES | TVS_SHOWSELALWAYS | TVS_HASBUTTONS | TVS_NOHSCROLL | TVS_EX_FADEINOUTEXPANDOS;


	return CTreeCtrl::PreCreateWindow(cs);
}

BOOL CGDBTreeCtrl::SetPath(CString strGdbPath)
{;
	HRESULT hr = m_pWorksFactory.CreateInstance(CLSID_FileGDBWorkspaceFactory);
	if (FAILED(hr))
	{
		AfxMessageBox("Error");
		return FALSE;
	}

	hr = m_pWorksFactory->OpenFromFile(CComBSTR(strGdbPath), 0, &m_pWorkspace);
	if (FAILED(hr))
	{
		AfxMessageBox("Error");
		return FALSE;
	}

	m_strPath = strGdbPath;
	return TRUE;
}

BOOL CGDBTreeCtrl::Populate()
{
	Cleanup();
	HTREEITEM hRoot = GetRootItem();
		
	IEnumDatasetPtr pEnumDataset;
	HRESULT hr = m_pWorkspace->get_Datasets(esriDTAny, &pEnumDataset);
	if (FAILED(hr))
	{
		return FALSE;
	}

	IDatasetPtr pDataset;
	pEnumDataset->Reset();
	while (SUCCEEDED(hr = pEnumDataset->Next(&pDataset)))
	{
		if (pDataset == NULL)
		{
			break;
		}
		CComBSTR bstrName;
		pDataset->get_Name(&bstrName);
		_bstr_t b = bstrName;
		char* szName = b;

		esriDatasetType type;
		pDataset->get_Type(&type);

		int icon = 0;
		switch (type)
		{
		case esriDTFeatureClass:
		{	
			IFeatureClassPtr pFeatureClass(pDataset);
			esriGeometryType geomType;
			pFeatureClass->get_ShapeType(&geomType);
			switch (geomType)
			{
			case esriGeometryPoint:
			case esriGeometryMultipoint:
				icon = CK_GDB_TREE_PONT_NODE;
				break;
			case esriGeometryLine:
			case esriGeometryPolyline:
				icon = CK_GDB_TREE_LINE_NODE;
				break;
			case esriGeometryPolygon:
				icon = CK_GDB_TREE_POLG_NODE;
				break;
			}
		}			
			break;
		case esriDTRasterDataset:
			icon = CK_GDB_TREE_GRID_NODE;
			break;
		}
		

		HTREEITEM hItem = InsertItem(szName, icon, icon, hRoot);
		SetItemData(hItem, (DWORD)type);
	}

	Expand(hRoot, TVE_EXPAND);


	return TRUE;
}


void CGDBTreeCtrl::Cleanup()
{
	HTREEITEM hItem, hSibling;
	HTREEITEM hRoot = GetRootItem();
	hItem = GetChildItem(hRoot);
	while (hItem)
	{
		hSibling = this->GetNextSiblingItem(hItem);
		this->DeleteItem(hItem);
		hItem = hSibling;
	}
}


void CGDBTreeCtrl::OnGdbTreeRefresh()
{
	// TODO: 在此添加命令处理程序代码
	this->Populate();
}
